﻿using System;
using System.Drawing;

namespace Swsk33.BasicGISGDI.Model
{
	/// <summary>
	/// 二维向量类
	/// </summary>
	public class Vector
	{
		private double x;

		private double y;

		/// <summary>
		/// 向量终止X坐标
		/// </summary>
		public double X { get => x; set => x = value; }

		/// <summary>
		/// 向量终止Y坐标
		/// </summary>
		public double Y { get => y; set => y = value; }

		/// <summary>
		/// 用一个坐标初始化向量
		/// </summary>
		/// <param name="x">向量X坐标</param>
		/// <param name="y">向量Y坐标</param>
		public Vector(double x, double y)
		{
			X = x;
			Y = y;
		}

		/// <summary>
		/// 用两个点初始化向量
		/// </summary>
		/// <param name="start">起始点</param>
		/// <param name="end">终止点</param>
		public Vector(Point start, Point end)
		{
			X = end.X - start.X;
			Y = end.Y - start.Y;
		}

		/// <summary>
		/// 用线段初始化一个向量
		/// </summary>
		/// <param name="lineSegment">线段</param>
		public Vector(LineSegment lineSegment)
		{
			X = lineSegment.End.X - lineSegment.Start.X;
			Y = lineSegment.End.Y - lineSegment.Start.Y;
		}

		/// <summary>
		/// 获取自身长度
		/// </summary>
		/// <returns>向量长度</returns>
		public double GetLength()
		{
			return Math.Sqrt(Math.Pow(X, 2) + Math.Pow(Y, 2));
		}

		/// <summary>
		/// 获取自身的单位向量
		/// </summary>
		/// <returns>自身单位向量</returns>
		public Vector GetUnitVector()
		{
			double length = GetLength();
			Vector vector = new Vector(X / length, Y / length);
			return vector;
		}

		/// <summary>
		/// 将自身和传入向量点乘
		/// </summary>
		/// <param name="vector">传入向量</param>
		/// <returns>点乘结果</returns>
		public double PointProduct(Vector vector)
		{
			return X * vector.X + Y * vector.Y;
		}

		/// <summary>
		/// 将自身和传入向量叉乘
		/// </summary>
		/// <param name="vector">传入向量</param>
		/// <returns>叉乘结果</returns>
		public double CrossProduct(Vector vector)
		{
			return X * vector.Y - vector.X * Y;
		}

		/// <summary>
		/// 获得自身和传入向量夹角
		/// </summary>
		/// <param name="vector">传入向量</param>
		/// <returns>与传入向量的夹角，角度制，范围0-180</returns>
		public double GetAngle(Vector vector)
		{
			return Math.Abs(Math.Acos(PointProduct(vector) / (GetLength() * vector.GetLength())) / Math.PI * 180);
		}
	}
}